#include "Datalyzer.h"
#include "Method.h"
#include "StringOps.h"
#include "Keywords.h"

#include<iostream>
#include<string>

using namespace std;

Datalyzer::Datalyzer(void)
{
	m_pxCurrentScope = NULL;
	m_nSerialNumber = 0;
}

Datalyzer::~Datalyzer(void)
{
}

void Datalyzer::onNewToken(Scope& inScope, Token& inToken)
{
	//All functionality currently in Symbolyzer
	inScope;
	inToken;
}

void Datalyzer::onScopeEntry(Scope& inNewScope, Scope& inOldScope)
{
	//All functionality currently in Symbolyzer
	m_pxCurrentScope = &inNewScope;
	inOldScope;
}

void Datalyzer::onScopeExit(Scope& inNewScope, Scope& inOldScope)
{
	//All functionality currently in Symbolyzer
	m_pxCurrentScope = &inNewScope;
	inOldScope;
}

void Datalyzer::printScopeSymbols(Scope* pxScope, MinesweeperOptions* pxOpt)
{
	static char* asSymbolType[]=
	{
		"Unknown",
		"Function",
		"Variable",
		"DataType",
		"Attribute"
	};

	static char* asScopeType[]=
	{
        "Invalid",
		"Global",
        "Parentheses",
        "CommentC",
        "CommentCPP",
        "Block",
        "Bracket",
        "Preprocessor", 
        "Literal"
	};

	bool bNoHeading		 = pxOpt->m_bNoHeading;
	bool bListOnly	 = pxOpt->m_bListOnly;
	bool bReport	 = pxOpt->m_bReport;
	bool bNoNumbering  = pxOpt->m_bNoNumbering;

	SymbolTable* pxSymbolTable = pxScope->m_pxSymbolTable;
	int nSymbols = pxSymbolTable->getSize();
	Symbol::Type eType;
	Symbol* pxSymbol;
	bool bShow;

	for(int i=0; i<nSymbols; i++)
	{
		pxSymbol = pxSymbolTable->m_apxSymbol[i];
		eType = pxSymbol->m_eSymbolType;

		bShow=false;
		switch(eType)
		{
		case Symbol::eSymbolAttribute:
			if(pxOpt->m_bAttributes)	bShow=true;
			break;

		case Symbol::eSymbolDataType:
			if(pxOpt->m_bDataTypes)		bShow=true;
			break;

		case Symbol::eSymbolFunction:
			if(pxOpt->m_bFunctions)		bShow=true;
			break;

		case Symbol::eSymbolVariable:
			if(pxOpt->m_bVariables)		bShow=true;
			break;
		}

		if(bShow)
		{
			m_nSerialNumber++;

			if(bReport)
			{
				cout<<"Symbol:("<<m_nSerialNumber << ")"<<endl;
				cout<<"Type:"<<asSymbolType[pxSymbol->m_eSymbolType] <<endl;
				cout<<"Name:"<<pxSymbol->m_sName<<endl;
				cout<<"Data Type:"<<pxSymbol->m_sTypePrefix <<endl;
				
				if(pxScope->m_sName!="") 
					cout<<"Defined In:"<<pxScope->m_sName<<endl;
				else
					cout<<"Defined In:"<<asScopeType[pxScope->getScopeType()]<<endl;
				cout<<"Line Number:"<<pxSymbol->m_xDefinition.m_nLineNumber<<endl;

				cout<<"Summary:";
			}
			
			if(!bReport)
				if(!bNoNumbering)
					cout<<m_nSerialNumber <<",";
				
			if(!bListOnly)
			{
				cout<<asSymbolType[pxSymbol->m_eSymbolType] <<",";
				cout<<pxSymbol->m_sName<<",";
				cout<<pxSymbol->m_sTypePrefix <<",";
				if(pxScope->m_sName!="") 
					cout<<pxScope->m_sName<<",";
				else
					cout<<asScopeType[pxScope->getScopeType()]<<",";
				
				cout<<pxSymbol->m_xDefinition.m_nLineNumber;
			}
			cout<<endl;

			if(bReport)
				cout<<endl;
		}
	}

	int nChildren = pxScope->m_apxChild.size();
	Scope *pxCursor;
	for(int i=0; i< nChildren; i++)
	{
		pxCursor = pxScope->m_apxChild[i];
		printScopeSymbols(pxCursor, pxOpt);
	}
	
}

void Datalyzer::print(MinesweeperOptions* pxOpt)
{
	Scope* pxCursor = NULL;

	bool bNoHeading		 = pxOpt->m_bNoHeading;
	bool bListOnly	 = pxOpt->m_bListOnly;
	bool bReport	 = pxOpt->m_bReport;
	bool bNoNumbering  = pxOpt->m_bNoNumbering;

	if (!((true==bNoHeading)||(true==bReport)||(true==bListOnly)))
	{
		if(!bNoNumbering)
			cout<<"Index,";
		cout<<"SymbolType,Name,DataType,ContainingScope,LineNumber\n";
		cout<<endl;
	}

	printScopeSymbols(m_pxCurrentScope, pxOpt);
	
}

	

